#ifndef __SINGAPOREBUSSERVICEROUTEVIEW__
#define __SINGAPOREBUSSERVICEROUTEVIEW__

// [[[ begin generated region: do not modify [Generated Includes]
#include <aknview.h>
// ]]] end generated region [Generated Includes]

#include "googlepositioning.h"
#include "positionrequest.h"
#include "SingaporeBusStructures.h"
#include "AsyncFileLoader.h"
#include "IteratorControl.h"
#include "ArrivalTimeQuery.h"
#include <aknsbasicbackgroundcontrolcontext.h>
#include "IrisQuery.h"
#include "SmrtQuery.h"
#include "CSingaporeBusGenericView.h"
#include "SingaporeBusAppUi.h"


class CSingaporeBusServiceRouteView : public CSingaporeBusGenericView<const CArrivalTimeItem*, CSingaporeBusServiceRouteView>
	{
	
	public:
	RArray<const CArrivalTimeItem*> iItems;
	const TService* iSelectedService;

	
	

	virtual TBool FilterItem(const CArrivalTimeItem* aItem, const TDesC8& aSearchText) { return CSingaporeBusGenericHandler::FilterItem(aItem, aSearchText); }
	virtual TReal32 OrderItem(const CArrivalTimeItem* aItem) { return CSingaporeBusGenericHandler::OrderItem(aItem); }
	virtual TBool ListBoxObserver(const CArrivalTimeItem* aItem, CEikListBox* aListBox, MEikListBoxObserver::TListBoxEvent aEventType)  { return CSingaporeBusGenericHandler::ListBoxObserver(aItem, aListBox, aEventType); }
	virtual TBool HandleCommandL( const CArrivalTimeItem* aItem, TInt aCommand )
		{
		this->iContainer->iIteratorControl->DrawDeferred();
		return CSingaporeBusGenericHandler::HandleCommandL(aItem, aCommand);
		}
	virtual CEikListBox* CreateListBoxL()
		{
		CSingaporeBusDocument* doc = (CSingaporeBusDocument*)CEikonEnv::Static()->EikAppUi()->Document();
		const TInt minHeight = doc->iSingaporeBusDrawItemsSG->PrimaryFont()->FontMaxHeight() + doc->iSingaporeBusDrawItemsSG->SecondaryFont()->FontMaxHeight()*2;
		return ConstructListBoxL(
				new (ELeave) CSingaporeBusListBox,
				minHeight + (ClientRect().Height() % minHeight)/(ClientRect().Height() / minHeight)
				);
		}
	virtual void FormatItem(TDes& aBuf, const CArrivalTimeItem* aItem)
		{
		
		CSingaporeBusDocument* doc = (CSingaporeBusDocument*)CEikonEnv::Static()->EikAppUi()->Document();
		
		aBuf.Format(_L("7\t%S"), narrowToWideLC(aItem->iStation->iStationNumber));
		CleanupStack::PopAndDestroy();
		if(aItem->iStation)
			{
			aBuf.AppendFormat(_L(" \x2022 %S"), narrowToWideLC(aItem->iStation->iAddress2));
			CleanupStack::PopAndDestroy();
			}
		aBuf.AppendFormat(_L("\t"));

		switch(aItem->iRequestStatus)
			{
			case CArrivalTimeQuery::ERequestWait:
				aBuf.AppendFormat(_L("select to request"));
				break;
			case CArrivalTimeQuery::ERequestPending:
				aBuf.AppendFormat(_L("requesting..."));
				break;
			case CArrivalTimeQuery::ERequestPendingInitialization:
				aBuf.AppendFormat(_L("waiting initialisation..."));
				break;
			case CArrivalTimeQuery::ERequestCompleted:
				aBuf.AppendFormat(_L("%S \xf814 %S"), aItem->iNextBus, aItem->iSubsequentBus);
				break;
			case CArrivalTimeQuery::ERequestUnavailable:
				aBuf.AppendFormat(_L("arrival time unavailable"));
				break;
			case CArrivalTimeQuery::ERequestError:
				aBuf.AppendFormat(_L("error (%S, %S)"), aItem->iNextBus, aItem->iSubsequentBus);
				break;
			}
		aBuf.AppendFormat(_L("\t"));
		{
		TBuf8<128> favoriteStr;
		doc->StoreFavoriteL(favoriteStr, aItem->iStation, aItem->iService);
		TBool isFavorite = EFalse;
		for(TInt i = 0 ; i < doc->iFavorites.Count() && !isFavorite; ++i)
			isFavorite = ((doc->iFavorites[i])->Find(favoriteStr) != NULL);
		if(isFavorite)
			aBuf.Append('0');
		}
		
		}
	
	
	void DrawItem(CSingaporeBusListBoxItemDrawer* aDrawer, const CArrivalTimeItem* aItem,
			TInt aItemIndex, const TRect& aActualItemRect,
			TBool aItemIsCurrent, TBool aViewIsEmphasized, TBool aViewIsDimmed, 
			TBool aItemIsSelected)
		{
		
		CSingaporeBusDocument* doc = (CSingaporeBusDocument*)CEikonEnv::Static()->EikAppUi()->Document();

		if(aItem->iService->iOperator == _L8("TFL"))
			doc->iSingaporeBusDrawItemsLD->DrawBusServiceRouteItemL(aDrawer, aItem, aItemIndex, aActualItemRect, aItemIsCurrent, aViewIsEmphasized, aViewIsDimmed, aItemIsSelected);
		else
			doc->iSingaporeBusDrawItemsSG->DrawBusServiceRouteItemL(aDrawer, aItem, aItemIndex, aActualItemRect, aItemIsCurrent, aViewIsEmphasized, aViewIsDimmed, aItemIsSelected);
		
		}
	
	
	void ConstructL()
		{
		CSingaporeBusGenericView<const CArrivalTimeItem*, CSingaporeBusServiceRouteView>::ConstructL( R_SINGAPORE_BUS_SERVICE_ROUTE_VIEW, R_SINGAPORE_BUS_SERVICE_ROUTE_MARK_MENU, R_SINGAPORE_BUS_SERVICE_ROUTE_ICONS, ESingaporeBusServiceRouteViewId );
		}
	virtual ~CSingaporeBusServiceRouteView()
		{
		iItems.Close();
		}
						
	void NotifyFileLoaded(const CAsyncFileLoader* aFile)
		{
		
		}
	
	void NotifyConnected()
		{
		for(TInt i = 0 ; i < iItems.Count() ; ++i)
			{
			if(iItems[i]->iRequestStatus == CArrivalTimeQuery::ERequestError)
				iItems[i]->iArrivalTimeQuery->SubmitL();
			}
		
		}
	
	void DoDeactivate()
		{
		this->SetEmptyUnderlyingL();
		for(TInt i = 0 ; i < iItems.Count() ; ++i)
			delete iItems[i];
		iItems.Reset();
		CSingaporeBusGenericView<const CArrivalTimeItem*, CSingaporeBusServiceRouteView>::DoDeactivate();
		}
	
	

protected:
	void DoActivateL(
		const TVwsViewId& aPrevViewId,
		TUid aCustomMessageId,
		const TDesC8& aCustomMessage )
		{
		CSingaporeBusGenericView<const CArrivalTimeItem*, CSingaporeBusServiceRouteView>::DoActivateL(aPrevViewId, aCustomMessageId, aCustomMessage );
		iSelectedService = NULL;
		{
		TPtrC8 field, value, remainder(aCustomMessage);
		while(ParseCustomMessageParamL(field, value, remainder))
			{
			if(field == _L8("id"))
				{
				CSingaporeBusDocument* doc = (CSingaporeBusDocument*)CEikonEnv::Static()->EikAppUi()->Document();
				TBuf8<15> strServiceKeyUpper(value);
				strServiceKeyUpper.UpperCase();
				TService target = { strServiceKeyUpper };
				TInt ret = doc->iServicesSortedByServiceKey.SpecificFindInOrder(&target, TLinearOrder<const TService*>(&CSingaporeBusDocument::TLinearOrder_Service), EArrayFindMode_Any);
				iSelectedService = (ret != KErrNotFound) ? doc->iServicesSortedByServiceKey[ret] : NULL;
				}
			}
		}
		InitializeList();
		RestoreViewStateL(aCustomMessage);
		{
		TPtrC8 field, value, remainder(aCustomMessage);
		while(ParseCustomMessageParamL(field, value, remainder))
			{
			if(field == _L8("station"))
				{
				TInt i = 0;
				for(i = 0 ; i < iItems.Count() && iItems[i]->iStation->iStationNumber != value ; ++i);
				if(i < iItems.Count())
					{
					iContainer->iIteratorControl->iListBox->SetCurrentItemIndex(i);
					iContainer->iIteratorControl->iListBox->ScrollToMakeItemVisible(i);
					iContainer->iIteratorControl->iListBox->DrawDeferred();
					}
				}
			}
		}
		}

	void StoreViewStateL(TDes8& aCustomMessage)
		{
		StoreCustomMessageParamL(aCustomMessage, _L8("id"), _L8("%S"), &iSelectedService->iServiceKey);
		CSingaporeBusGenericView<const CArrivalTimeItem*, CSingaporeBusServiceRouteView>::StoreViewStateL(aCustomMessage);
		}
	
	void InitializeList()
		{
	TFunTrace funTrace(__PRETTY_FUNCTION__);

		CSingaporeBusDocument* doc = (CSingaporeBusDocument*)CEikonEnv::Static()->EikAppUi()->Document();
		if(!iSelectedService) return;
		if(!doc->iStationsSortedByStationNumber.Count()) return; // everything must be loaded
		this->SetEmptyUnderlyingL();
		for(TInt i = 0 ; i < iItems.Count() ; ++i)
			delete iItems[i];
		iItems.Reset();
		for(TInt j = iSelectedService->iStationsBeg ; j < iSelectedService->iStationsEnd ; ++j)
			{
			const TStation* station = NULL;
			{
			TStation target = { doc->iServiceStations[j] };
			TInt ret = doc->iStationsSortedByStationNumber.SpecificFindInOrder(&target, TLinearOrder<const TStation*>(&CSingaporeBusDocument::TLinearOrder_Station), EArrayFindMode_Any);
			station = (ret != KErrNotFound) ? doc->iStationsSortedByStationNumber[ret] : NULL;
			}
			if(station && iSelectedService)
				iItems.AppendL( CSingaporeBusGenericHandler::NewArrivalTimeItemL(station, iSelectedService, this) );
			}
		
		if(iItems.Count() > 0)
			{
			iUnderlying = 
					new (ELeave) CArrayIterator<const CArrivalTimeItem*>(&iItems[0], iItems.Count());
			iFilterIterator = new (ELeave) CFilteringIterator<const CArrivalTimeItem*>(
					iUnderlying.Get(),
					scalp::MakeFunctionL( scalp::Bind(&CSingaporeBusServiceRouteView::FilterItem, this, scalp::Free1, scalp::Ref(this->iSearchText)) )
					);
			this->iContainer->iIteratorControl->SetUnderlying( iFilterIterator.Get() );
			iContainer->iIteratorControl->iListBox->DrawDeferred();
			}
		else
			{
			this->SetEmptyUnderlyingL();
			iContainer->iIteratorControl->iListBox->View()->SetListEmptyTextL(_L("No stops found"));
			iContainer->iIteratorControl->iListBox->DrawDeferred();
			}
		}
	
		
	};

#endif // __SINGAPOREBUSSERVICEROUTEVIEW__
